package org.grid.model.rmi;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.grid.model.Node;
import org.grid.model.calculate.CalculatorOperation;

/**
 * Expõe o objeto da interface <code>LogCalculator</code> em um nó RMI
 * @author wellington
 */
public class LogCalculatorServer {

    /**
     * Porta padrão para a escuta do servidor
     */
    public static int DEFAULT_PORT = 45321;

    //<editor-fold desc="public methods">
    private Registry registry;
    private Node node;
    private LogCalculatorImpl logCalculatorImpl;
    //</editor-fold>

    //<editor-fold desc="public methods">
    /**
     * construtor utilizando a porta padrão <code>DEFAULT_PORT</code>
     */
    public LogCalculatorServer() {
        this(DEFAULT_PORT);
    }
    /**
     * Construtor utilizando uma porta diferente
     * @param port
     */
    public LogCalculatorServer(int port) {
        try {
            node = new Node("127.0.0.1", port, Node.DEFAULT_NAME);
            LocateRegistry.createRegistry(port);
        } catch (Exception ex) {
            Logger.getLogger(LogCalculatorServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //</editor-fold>

    //<editor-fold desc="public methods">
    /**
     * Inicia o servidor RMI com a classe de operação passada
     * @param operationClass o nome da classe a ser instanciada
     * @return sucesso caso consiga instanciar a classe passada e iniciar o servidor RMI
     */
    public boolean startServer(String operationClass) {
        try {
            //carrega a classe de operação
            Object operation = Class.forName(operationClass).newInstance();
            logCalculatorImpl = new LogCalculatorImpl((CalculatorOperation) operation);
            node.setLogCalculator((LogCalculator) UnicastRemoteObject.exportObject(logCalculatorImpl, 0));
            registry = LocateRegistry.getRegistry(node.getAddress(), node.getPort());
            registry.bind(node.getDescription(), node.getLogCalculator());
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
    /**
     * Para o servidor RMI
     * @return sucesso caso consiga parar o servidor sem erros
     */
    public boolean stopServer() {
        try {
            if (getRegistry() != null) {
                getRegistry().unbind(Node.DEFAULT_NAME);
                return true;
            } else {
                return false;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
    //</editor-fold>

    //<editor-fold desc="getters/setters">
    public Registry getRegistry() {
        return registry;
    }

    public Node getNode() {
        return node;
    }

    public LogCalculatorImpl getLogCalculatorImpl() {
        return logCalculatorImpl;
    }
    //</editor-fold>
}
